.486p
.model flat
.code

        include input.h
        include equates.h
        include macros.h
        include data.h
        include debug.h
        include ppu.h
        include kb.h
        include file.h
        include empty.h
        include io.h
        include memory.h
        include sb.h

        public cpu_init
        public op_fetch
        public int_flags
        public op_table
        public cycles
        public framecycles
        public linecycles
        public ticks
        public framecount
        public drawn
        public fps
        public scanline
        public lastbank
        public lastaddr
        public scanlinehook
        public mapperreset
        public _Z_A
        public _X_Y
        public _S
        public _PC
        public Nflag
        public Cflag
        public Vflag
        public DIflag
;----------------------------------------------------------------------------
_??:;   ???                                     ;invalid opcode
;----------------------------------------------------------------------------
if DEBUG
        or [int_flags],DEBUG2                   ;enter debugger
        mov [debugmsg],offset msg42             ;'illegal opcode'
endif
        fetch 3*2
;----------------------------------------------------------------------------
_00:;   BRK
;----------------------------------------------------------------------------
if DEBUG
        or [int_flags],DEBUG2
        mov [debugmsg],offset msg07
        trace tBREAK,0
endif
        sub esi,[lastbank]
        mov eax,esi
        inc eax
        push16                                  ;save PC
        encodeP(B+R)                            ;save P
        push8 al
        or [DIflag],I                           ;disable IRQ
        mov edi,[memmap+7*4]
        movzx esi,word ptr [edi+BRK_VECTOR]
        encodePC                                ;get BRK vector
        fetch 3*7
;----------------------------------------------------------------------------
_01:;   ORA ($xx,X)
;----------------------------------------------------------------------------
        doIIX
        opORA
        fetch 3*6
;----------------------------------------------------------------------------
_05:;   ORA $xx
;----------------------------------------------------------------------------
        doZ
        opORA
        fetch 3*3
;----------------------------------------------------------------------------
_06:;   ASL $xx
;----------------------------------------------------------------------------
        doZ
        opASL
        fetch 3*5
;----------------------------------------------------------------------------
_08:;   PHP
;----------------------------------------------------------------------------
        encodeP(B+R)
        push8 al                                ;push 6502 flags
        fetch 3*3
;----------------------------------------------------------------------------
_09:;   ORA #$xx
;----------------------------------------------------------------------------
        doIMM
        opORA
        fetch 3*2
;----------------------------------------------------------------------------
_0A:;   ASL
;----------------------------------------------------------------------------
        shl dl,1
        mov dh,dl       ;Z
        mov [Nflag],dl  ;N
        rcl [Cflag],1   ;C
        fetch 3*2
;----------------------------------------------------------------------------
_0D:;   ORA $xxxx
;----------------------------------------------------------------------------
        doABS
        opORA
        fetch 3*4
;----------------------------------------------------------------------------
_0E:;   ASL $xxxx
;----------------------------------------------------------------------------
        doABS
        opASL
        fetch 3*6
;----------------------------------------------------------------------------
_10:;   BPL
;----------------------------------------------------------------------------
        test [Nflag],N
        jnz _BPL

        movsx edi,byte ptr [esi]
        lea eax,[esi+1]
        lea esi,[esi+edi+1]
        xor eax,esi
        shr ah,1
        sbb eax,eax
        and eax,3
        sub [cycles],eax
        fetch 3*3
_BPL:
        inc esi
        fetch 3*2
;----------------------------------------------------------------------------
_11:;   ORA ($xx),Y
;----------------------------------------------------------------------------
        doIIY2
        opORA
        fetch 3*5
;----------------------------------------------------------------------------
_15:;   ORA $xx,X
;----------------------------------------------------------------------------
        doZIX
        opORA
        fetch 3*4
;----------------------------------------------------------------------------
_16:;   ASL $xx,X
;----------------------------------------------------------------------------
        doZIX
        opASL
        fetch 3*6
;----------------------------------------------------------------------------
_18:;   CLC
;----------------------------------------------------------------------------
        mov [Cflag],0
        fetch 3*2
;----------------------------------------------------------------------------
_19:;   ORA $xxxx,Y
;----------------------------------------------------------------------------
        doAIY2
        opORA
        fetch 3*4
;----------------------------------------------------------------------------
_1D:;   ORA $xxxx,X
;----------------------------------------------------------------------------
        doAIX2
        opORA
        fetch 3*4
;----------------------------------------------------------------------------
_1E:;   ASL $xxxx,X
;----------------------------------------------------------------------------
        doAIX
        opASL
        fetch 3*7
;----------------------------------------------------------------------------
_20:;   JSR $xxxx
;----------------------------------------------------------------------------
        mov eax,esi
        sub eax,[lastbank]
        inc eax
        push16
        movzx esi,word ptr [esi]
if DEBUG
        cmp esi,[jsrminaddr]
        jb _200
        cmp esi,[jsrmaxaddr]
        ja _200
        or [int_flags],DEBUG2
        mov [debugmsg],offset msg15
;        mov [jsrminaddr],-1
  _200:
endif
        encodePC
        fetch 3*6
;----------------------------------------------------------------------------
_21:;   AND ($xx,X)
;----------------------------------------------------------------------------
        doIIX
        opAND
        fetch 3*6
;----------------------------------------------------------------------------
_24:;   BIT $xx
;----------------------------------------------------------------------------
        doZ
        opBIT
        fetch 3*3
;----------------------------------------------------------------------------
_25:;   AND $xx
;----------------------------------------------------------------------------
        doZ
        opAND
        fetch 3*3
;----------------------------------------------------------------------------
_26:;   ROL $xx
;----------------------------------------------------------------------------
        doZ
        opROL
        fetch 3*5
;----------------------------------------------------------------------------
_28:;   PLP
;----------------------------------------------------------------------------
        pop8 dh                 ;pop 6502 flags and decode
        decodeP
        fetch 3*4
;----------------------------------------------------------------------------
_29:;   AND #$xx
;----------------------------------------------------------------------------
        doIMM
        opAND
        fetch 3*2
;----------------------------------------------------------------------------
_2A:;   ROL
;----------------------------------------------------------------------------
        shr [Cflag],1
        rcl dl,1
        rcl [Cflag],1   ;C
        mov dh,dl       ;Z
        mov [Nflag],dl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_2C:;   BIT $xxxx
;----------------------------------------------------------------------------
        doABS
        opBIT
        fetch 3*4
;----------------------------------------------------------------------------
_2D:;   AND $xxxx
;----------------------------------------------------------------------------
        doABS
        opAND
        fetch 3*4
;----------------------------------------------------------------------------
_2E:;   ROL $xxxx
;----------------------------------------------------------------------------
        doABS
        opROL
        fetch 3*6
;----------------------------------------------------------------------------
_30:;   BMI
;----------------------------------------------------------------------------
        test [Nflag],N
        jz _BMI

        movsx edi,byte ptr [esi]
        lea eax,[esi+1]
        lea esi,[esi+edi+1]
        xor eax,esi
        shr ah,1
        sbb eax,eax
        and eax,3
        sub [cycles],eax
        fetch 3*3
_BMI:
        inc esi
        fetch 3*2
;----------------------------------------------------------------------------
_31:;   AND ($xx),Y
;----------------------------------------------------------------------------
        doIIY2
        opAND
        fetch 3*5
;----------------------------------------------------------------------------
_35:;   AND $xx,X
;----------------------------------------------------------------------------
        doZIX
        opAND
        fetch 3*4
;----------------------------------------------------------------------------
_36:;   ROL $xx,X
;----------------------------------------------------------------------------
        doZIX
        opROL
        fetch 3*6
;----------------------------------------------------------------------------
_38:;   SEC
;----------------------------------------------------------------------------
        mov [Cflag],1
        fetch 3*2
;----------------------------------------------------------------------------
_39:;   AND $xxxx,Y
;----------------------------------------------------------------------------
        doAIY2
        opAND
        fetch 3*4
;----------------------------------------------------------------------------
_3D:;   AND $xxxx,X
;----------------------------------------------------------------------------
        doAIX2
        opAND
        fetch 3*4
;----------------------------------------------------------------------------
_3E:;   ROL $xxxx,X
;----------------------------------------------------------------------------
        doAIX
        opROL
        fetch 3*7
;----------------------------------------------------------------------------
_40:;   RTI
;----------------------------------------------------------------------------
        pop8 dh                 ;pop 6502 flags and decode
        decodeP
        pop16                   ;pop the return address
        mov esi,eax
        encodePC
        fetch 3*6
;----------------------------------------------------------------------------
_41:;   EOR ($xx,X)
;----------------------------------------------------------------------------
        doIIX
        opEOR
        fetch 3*6
;----------------------------------------------------------------------------
_45:;   EOR $xx
;----------------------------------------------------------------------------
        doZ
        opEOR
        fetch 3*3
;----------------------------------------------------------------------------
_46:;   LSR $xx
;----------------------------------------------------------------------------
        doZ
        opLSR
        fetch 3*5
;----------------------------------------------------------------------------
_48:;   PHA
;----------------------------------------------------------------------------
        push8 dl
        fetch 3*3
;----------------------------------------------------------------------------
_49:;   EOR #$xx
;----------------------------------------------------------------------------
        doIMM
        opEOR
        fetch 3*2
;----------------------------------------------------------------------------
_4A:;   LSR
;----------------------------------------------------------------------------
        mov [Cflag],dl  ;C
        shr dl,1
        mov dh,dl       ;Z
        mov [Nflag],dl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_4C:;   JMP $xxxx
;----------------------------------------------------------------------------
        movzx esi,word ptr [esi]
        encodePC
        fetch 3*3
;----------------------------------------------------------------------------
_4D:;   EOR $xxxx
;----------------------------------------------------------------------------
        doABS
        opEOR
        fetch 3*4
;----------------------------------------------------------------------------
_4E:;   LSR $xxxx
;----------------------------------------------------------------------------
        doABS
        opLSR
        fetch 3*6
;----------------------------------------------------------------------------
_50:;   BVC
;----------------------------------------------------------------------------
        cmp [Vflag],0
        jne _BVC

        movsx edi,byte ptr [esi]
        lea eax,[esi+1]
        lea esi,[esi+edi+1]
        xor eax,esi
        shr ah,1
        sbb eax,eax
        and eax,3
        sub [cycles],eax
        fetch 3*3
_BVC:
        inc esi
        fetch 3*2
;----------------------------------------------------------------------------
_51:;   EOR ($xx),Y
;----------------------------------------------------------------------------
        doIIY2
        opEOR
        fetch 3*5
;----------------------------------------------------------------------------
_55:;   EOR $xx,X
;----------------------------------------------------------------------------
        doZIX
        opEOR
        fetch 3*4
;----------------------------------------------------------------------------
_56:;   LSR $xx,X
;----------------------------------------------------------------------------
        doZIX
        opLSR
        fetch 3*6
;----------------------------------------------------------------------------
_58:;   CLI
;----------------------------------------------------------------------------
        and [DIflag],not I
        fetch 3*2
;----------------------------------------------------------------------------
_59:;   EOR $xxxx,Y
;----------------------------------------------------------------------------
        doAIY2
        opEOR
        fetch 3*4
;----------------------------------------------------------------------------
_5D:;   EOR $xxxx,X
;----------------------------------------------------------------------------
        doAIX2
        opEOR
        fetch 3*4
;----------------------------------------------------------------------------
_5E:;   LSR $xxxx,X
;----------------------------------------------------------------------------
        doAIX
        opLSR
        fetch 3*7
;----------------------------------------------------------------------------
_60:;   RTS
;----------------------------------------------------------------------------
        pop16
        lea esi,[eax+1]
        encodePC
        fetch 3*6
;----------------------------------------------------------------------------
_61:;   ADC ($xx,X)
;----------------------------------------------------------------------------
        doIIX
        opADC
        fetch 3*6
;----------------------------------------------------------------------------
_65:;   ADC $xx
;----------------------------------------------------------------------------
        doZ
        opADC
        fetch 3*3
;----------------------------------------------------------------------------
_66:;   ROR $xx
;----------------------------------------------------------------------------
        doZ
        opROR
        fetch 3*5
;----------------------------------------------------------------------------
_68:;   PLA
;----------------------------------------------------------------------------
        pop8 dl
        mov dh,dl       ;Z
        mov [Nflag],dl  ;N
        fetch 3*4
;----------------------------------------------------------------------------
_69:;   ADC #$xx
;----------------------------------------------------------------------------
        doIMM
        opADC
        fetch 3*2
;----------------------------------------------------------------------------
_6A:;   ROR
;----------------------------------------------------------------------------
        shr [Cflag],1
        mov [Cflag],dl  ;C
        rcr dl,1
        mov dh,dl       ;Z
        mov [Nflag],dl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_6C:;   JMP ($xxxx)
;----------------------------------------------------------------------------
        movzx edi,word ptr [esi]
        mov esi,edi
        shr edi,13
        add esi,[memmap+edi*4]
        movzx esi,word ptr [esi]
        encodePC
        fetch 3*5
;----------------------------------------------------------------------------
_6D:;   ADC $xxxx
;----------------------------------------------------------------------------
        doABS
        opADC
        fetch 3*4
;----------------------------------------------------------------------------
_6E:;   ROR $xxxx
;----------------------------------------------------------------------------
        doABS
        opROR
        fetch 3*6
;----------------------------------------------------------------------------
_70:;   BVS                                                                *
;----------------------------------------------------------------------------
        cmp [Vflag],0
        je _BVS

        movsx edi,byte ptr [esi]
        lea eax,[esi+1]
        lea esi,[esi+edi+1]
        xor eax,esi
        shr ah,1
        sbb eax,eax
        and eax,3
        sub [cycles],eax
        fetch 3*3
_BVS:
        inc esi
        fetch 3*2
;----------------------------------------------------------------------------
_71:;   ADC ($xx),Y
;----------------------------------------------------------------------------
        doIIY2
        opADC
        fetch 3*5
;----------------------------------------------------------------------------
_75:;   ADC $xx,X
;----------------------------------------------------------------------------
        doZIX
        opADC
        fetch 3*4
;----------------------------------------------------------------------------
_76:;   ROR $xx,X
;----------------------------------------------------------------------------
        doZIX
        opROR
        fetch 3*6
;----------------------------------------------------------------------------
_78:;   SEI
;----------------------------------------------------------------------------
        or [DIflag],I
        fetch 3*2
;----------------------------------------------------------------------------
_79:;   ADC $xxxx,Y
;----------------------------------------------------------------------------
        doAIY2
        opADC
        fetch 3*4
;----------------------------------------------------------------------------
_7D:;   ADC $xxxx,X
;----------------------------------------------------------------------------
        doAIX2
        opADC
        fetch 3*4
;----------------------------------------------------------------------------
_7E:;   ROR $xxxx,X
;----------------------------------------------------------------------------
        doAIX
        opROR
        fetch 3*7
;----------------------------------------------------------------------------
_81:;   STA ($xx,X)
;----------------------------------------------------------------------------
        doIIX
        opSTA
        fetch 3*6
;----------------------------------------------------------------------------
_84:;   STY $xx
;----------------------------------------------------------------------------
        doZ
        opSTY
        fetch 3*3
;----------------------------------------------------------------------------
_85:;   STA $xx
;----------------------------------------------------------------------------
        doZ
        opSTA
        fetch 3*3
;----------------------------------------------------------------------------
_86:;   STX $xx
;----------------------------------------------------------------------------
        doZ
        opSTX
        fetch 3*3
;----------------------------------------------------------------------------
_88:;   DEY
;----------------------------------------------------------------------------
        dec cl
        mov dh,cl       ;Z
        mov [Nflag],cl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_8A:;   TXA
;----------------------------------------------------------------------------
        mov dl,ch
        mov dh,ch       ;Z
        mov [Nflag],ch  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_8C:;   STY $xxxx
;----------------------------------------------------------------------------
        doABS
        opSTY
        fetch 3*4
;----------------------------------------------------------------------------
_8D:;   STA $xxxx
;----------------------------------------------------------------------------
        doABS
        opSTA
        fetch 3*4
;----------------------------------------------------------------------------
_8E:;   STX $xxxx
;----------------------------------------------------------------------------
        doABS
        opSTX
        fetch 3*4
;----------------------------------------------------------------------------
_90:;   BCC
;----------------------------------------------------------------------------
        test [Cflag],1
        jnz _BCC

        movsx edi,byte ptr [esi]
        lea eax,[esi+1]
        lea esi,[esi+edi+1]
        xor eax,esi
        shr ah,1
        sbb eax,eax
        and eax,3
        sub [cycles],eax
        fetch 3*3
_BCC:
        inc esi
        fetch 3*2
;----------------------------------------------------------------------------
_91:;   STA ($xx),Y
;----------------------------------------------------------------------------
        doIIY
        opSTA
        fetch 3*6
;----------------------------------------------------------------------------
_94:;   STY $xx,X
;----------------------------------------------------------------------------
        doZIX
        opSTY
        fetch 3*4
;----------------------------------------------------------------------------
_95:;   STA $xx,X
;----------------------------------------------------------------------------
        doZIX
        opSTA
        fetch 3*4
;----------------------------------------------------------------------------
_96:;   STX $xx,Y
;----------------------------------------------------------------------------
        doZIY
        opSTX
        fetch 3*4
;----------------------------------------------------------------------------
_98:;   TYA
;----------------------------------------------------------------------------
        mov dl,cl
        mov dh,cl       ;Z
        mov [Nflag],cl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_99:;   STA $xxxx,Y
;----------------------------------------------------------------------------
        doAIY
        opSTA
        fetch 3*5
;----------------------------------------------------------------------------
_9A:;   TXS
;----------------------------------------------------------------------------
        mov bl,ch
        fetch 3*2
;----------------------------------------------------------------------------
_9D:;   STA $xxxx,X
;----------------------------------------------------------------------------
        doAIX
        opSTA
        fetch 3*5
;----------------------------------------------------------------------------
_A0:;   LDY #$xx
;----------------------------------------------------------------------------
        doIMM
        opLDY
        fetch 3*2
;----------------------------------------------------------------------------
_A1:;   LDA ($xx,X)
;----------------------------------------------------------------------------
        doIIX
        opLDA
        fetch 3*6
;----------------------------------------------------------------------------
_A2:;   LDX #$xx
;----------------------------------------------------------------------------
        doIMM
        opLDX
        fetch 3*2
;----------------------------------------------------------------------------
_A4:;   LDY $xx
;----------------------------------------------------------------------------
        doZ
        opLDY
        fetch 3*3
;----------------------------------------------------------------------------
_A5:;   LDA $xx
;----------------------------------------------------------------------------
        doZ
        opLDA
        fetch 3*3
;----------------------------------------------------------------------------
_A6:;   LDX $xx
;----------------------------------------------------------------------------
        doZ
        opLDX
        fetch 3*3
;----------------------------------------------------------------------------
_A8:;   TAY
;----------------------------------------------------------------------------
        mov cl,dl
        mov dh,dl       ;Z
        mov [Nflag],dl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_A9:;   LDA #$xx
;----------------------------------------------------------------------------
        doIMM
        opLDA
        fetch 3*2
;----------------------------------------------------------------------------
_AA:;   TAX
;----------------------------------------------------------------------------
        mov ch,dl
        mov dh,dl       ;Z
        mov [Nflag],dl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_AC:;   LDY $xxxx
;----------------------------------------------------------------------------
        doABS
        opLDY
        fetch 3*4
;----------------------------------------------------------------------------
_AD:;   LDA $xxxx
;----------------------------------------------------------------------------
        doABS
        opLDA
        fetch 3*4
;----------------------------------------------------------------------------
_AE:;   LDX $xxxx
;----------------------------------------------------------------------------
        doABS
        opLDX
        fetch 3*4
;----------------------------------------------------------------------------
_B0:;   BCS                                                                *
;----------------------------------------------------------------------------
        test [Cflag],1
        jz _BCS

        movsx edi,byte ptr [esi]
        lea eax,[esi+1]
        lea esi,[esi+edi+1]
        xor eax,esi
        shr ah,1
        sbb eax,eax
        and eax,3
        sub [cycles],eax
        fetch 3*3
_BCS:
        inc esi
        fetch 3*2
;----------------------------------------------------------------------------
_B1:;   LDA ($xx),Y
;----------------------------------------------------------------------------
        doIIY2
        opLDA
        fetch 3*5
;----------------------------------------------------------------------------
_B4:;   LDY $xx,X
;----------------------------------------------------------------------------
        doZIX
        opLDY
        fetch 3*4
;----------------------------------------------------------------------------
_B5:;   LDA $xx,X
;----------------------------------------------------------------------------
        doZIX
        opLDA
        fetch 3*4
;----------------------------------------------------------------------------
_B6:;   LDX $xx,Y
;----------------------------------------------------------------------------
        doZIY
        opLDX
        fetch 3*4
;----------------------------------------------------------------------------
_B8:;   CLV
;----------------------------------------------------------------------------
        mov [Vflag],0
        fetch 3*2
;----------------------------------------------------------------------------
_B9:;   LDA $xxxx,Y
;----------------------------------------------------------------------------
        doAIY2
        opLDA
        fetch 3*4
;----------------------------------------------------------------------------
_BA:;   TSX
;----------------------------------------------------------------------------
        mov ch,bl
        mov dh,bl       ;Z
        mov [Nflag],bl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_BC:;   LDY $xxxx,X
;----------------------------------------------------------------------------
        doAIX2
        opLDY
        fetch 3*4
;----------------------------------------------------------------------------
_BD:;   LDA $xxxx,X
;----------------------------------------------------------------------------
        doAIX2
        opLDA
        fetch 3*4
;----------------------------------------------------------------------------
_BE:;   LDX $xxxx,Y
;----------------------------------------------------------------------------
        doAIY2
        opLDX
        fetch 3*4
;----------------------------------------------------------------------------
_C0:;   CPY #$xx
;----------------------------------------------------------------------------
        doIMM
        opCPY
        fetch 3*2
;----------------------------------------------------------------------------
_C1:;   CMP ($xx,X)
;----------------------------------------------------------------------------
        doIIX
        opCMP
        fetch 3*6
;----------------------------------------------------------------------------
_C4:;   CPY $xx
;----------------------------------------------------------------------------
        doZ
        opCPY
        fetch 3*3
;----------------------------------------------------------------------------
_C5:;   CMP $xx
;----------------------------------------------------------------------------
        doZ
        opCMP
        fetch 3*3
;----------------------------------------------------------------------------
_C6:;   DEC $xx
;----------------------------------------------------------------------------
        doZ
        opDEC
        fetch 3*5
;----------------------------------------------------------------------------
_C8:;   INY
;----------------------------------------------------------------------------
        inc cl
        mov dh,cl       ;Z
        mov [Nflag],cl  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_C9:;   CMP #$xx
;----------------------------------------------------------------------------
        doIMM
        opCMP
        fetch 3*2
;----------------------------------------------------------------------------
_CA:;   DEX
;----------------------------------------------------------------------------
        dec ch
        mov dh,ch       ;Z
        mov [Nflag],ch  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_CC:;   CPY $xxxx
;----------------------------------------------------------------------------
        doABS
        opCPY
        fetch 3*4
;----------------------------------------------------------------------------
_CD:;   CMP $xxxx
;----------------------------------------------------------------------------
        doABS
        opCMP
        fetch 3*4
;----------------------------------------------------------------------------
_CE:;   DEC $xxxx
;----------------------------------------------------------------------------
        doABS
        opDEC
        fetch 3*6
;----------------------------------------------------------------------------
_D0:;   BNE
;----------------------------------------------------------------------------
        cmp dh,0
        je _BNE

        movsx edi,byte ptr [esi]
        lea eax,[esi+1]
        lea esi,[esi+edi+1]
        xor eax,esi
        shr ah,1
        sbb eax,eax
        and eax,3
        sub [cycles],eax
        fetch 3*3
_BNE:
        inc esi
        fetch 3*2
;----------------------------------------------------------------------------
_D1:;   CMP ($xx),Y
;----------------------------------------------------------------------------
        doIIY2
        opCMP
        fetch 3*5
;----------------------------------------------------------------------------
_D5:;   CMP $xx,X
;----------------------------------------------------------------------------
        doZIX
        opCMP
        fetch 3*4
;----------------------------------------------------------------------------
_D6:;   DEC $xx,X
;----------------------------------------------------------------------------
        doZIX
        opDEC
        fetch 3*6
;----------------------------------------------------------------------------
_D8:;   CLD
;----------------------------------------------------------------------------        
        and [DIflag],not D
        fetch 3*2
;----------------------------------------------------------------------------
_D9:;   CMP $xxxx,Y
;----------------------------------------------------------------------------
        doAIY2
        opCMP
        fetch 3*4
;----------------------------------------------------------------------------
_DD:;   CMP $xxxx,X
;----------------------------------------------------------------------------
        doAIX2
        opCMP
        fetch 3*4
;----------------------------------------------------------------------------
_DE:;   DEC $xxxx,X
;----------------------------------------------------------------------------
        doAIX
        opDEC
        fetch 3*7
;----------------------------------------------------------------------------
_E0:;   CPX #$xx
;----------------------------------------------------------------------------
        doIMM
        opCPX
        fetch 3*2
;----------------------------------------------------------------------------
_E1:;   SBC ($xx,X)
;----------------------------------------------------------------------------
        doIIX
        opSBC
        fetch 3*6
;----------------------------------------------------------------------------
_E4:;   CPX $xx
;----------------------------------------------------------------------------
        doZ
        opCPX
        fetch 3*3
;----------------------------------------------------------------------------
_E5:;   SBC $xx
;----------------------------------------------------------------------------
        doZ
        opSBC
        fetch 3*3
;----------------------------------------------------------------------------
_E6:;   INC $xx
;----------------------------------------------------------------------------
        doZ
        opINC
        fetch 3*5
;----------------------------------------------------------------------------
_E8:;   INX
;----------------------------------------------------------------------------
        inc ch
        mov dh,ch       ;Z
        mov [Nflag],ch  ;N
        fetch 3*2
;----------------------------------------------------------------------------
_E9:;   SBC #$xx
;----------------------------------------------------------------------------
        doIMM
        opSBC
        fetch 3*2
;----------------------------------------------------------------------------
_EA:;   NOP
;----------------------------------------------------------------------------
        fetch 3*2
;----------------------------------------------------------------------------
_EC:;   CPX $xxxx
;----------------------------------------------------------------------------
        doABS
        opCPX
        fetch 3*4
;----------------------------------------------------------------------------
_ED:;   SBC $xxxx
;----------------------------------------------------------------------------
        doABS
        opSBC
        fetch 3*4
;----------------------------------------------------------------------------
_EE:;   INC $xxxx
;----------------------------------------------------------------------------
        doABS
        opINC
        fetch 3*6
;----------------------------------------------------------------------------
_F0:;   BEQ
;----------------------------------------------------------------------------
        cmp dh,0
        jne _BEQ

        movsx edi,byte ptr [esi]
        lea eax,[esi+1]
        lea esi,[esi+edi+1]
        xor eax,esi
        shr ah,1
        sbb eax,eax
        and eax,3
        sub [cycles],eax
        fetch 3*3
_BEQ:
        inc esi
        fetch 3*2
;----------------------------------------------------------------------------
_F1:;   SBC ($xx),Y
;----------------------------------------------------------------------------
        doIIY2
        opSBC
        fetch 3*5
;----------------------------------------------------------------------------
_F5:;   SBC $xx,X
;----------------------------------------------------------------------------
        doZIX
        opSBC
        fetch 3*4
;----------------------------------------------------------------------------
_F6:;   INC $xx,X
;----------------------------------------------------------------------------
        doZIX
        opINC
        fetch 3*6
;----------------------------------------------------------------------------
_F8:;   SED
;----------------------------------------------------------------------------
        or [DIflag],D
        fetch 3*2
;----------------------------------------------------------------------------
_F9:;   SBC $xxxx,Y
;----------------------------------------------------------------------------
        doAIY2
        opSBC
        fetch 3*4
;----------------------------------------------------------------------------
_FD:;   SBC $xxxx,X
;----------------------------------------------------------------------------
        doAIX2
        opSBC
        fetch 3*4
;----------------------------------------------------------------------------
_FE:;   INC $xxxx,X
;----------------------------------------------------------------------------
        doAIX
        opINC
        fetch 3*7
;----------------------------------------------------------------------------
align 4
op_fetch:;                      ;fetch+execute next opcode
;----------------------------------------------------------------------------
        fetch1
;----------------------------------------------------------------------------
cpu_init:;      initialize NES, begin execution
;----------------------------------------------------------------------------
        call sb_resume                  ;sound on
        mov eax,[framecount]            ;reset timer
        mov [ticks],eax

        xor ecx,ecx                     ;reset X,Y
        xor edx,edx                     ;reset A,P
        mov [Nflag],dl
        mov [Vflag],dl
        mov [Cflag],dl
        mov [DIflag],dl
        mov ebx,[ram_ptr]
        add ebx,01ffh                   ;reset S
reset:
        mov eax,offset stackend         ;reset stack
        mov esp,eax

        mov [cycles],0
        mov [framecycles],0
        mov [linecycles],0

        call ppureset
        call ioreset
        call [mapperreset]

        and [int_flags],not (RES+NMI+IRQ)   ;clear RES+NMI+IRQ
        or [DIflag],I                       ;disable IRQ
        mov edi,[memmap+7*4]
        movzx esi,word ptr [edi+RES_VECTOR]
        encodePC                                ;get reset vector
        save6502
frame:                  ;- - - - - - - -frame begin
        inc [framecount]
        mov [scanline],0
        trace tFRAME,0

        mov [framecycles],0

        call checkKB                            ;handle keyboard stuff
        call getinput                           ;deal with input devices
        call drawframe
        call updatesound

        mov al,[ctrl1]                          ;check for palette change
        and al,1
        xor [oldctrl1],al
        mov [oldctrl1],al
        jnz to0
        cmp [palchange],0
        je to1
to0:    call setnespal
        mov [palchange],0
to1:
                        ;- - - - - - - -lines 0-239
fr0:
        mov [linecycles],0
        cmp [spritechange],0
        je frxx
        call sortsprites                ;update sprites
frxx:
        xor eax,eax                     ;new line
        call drawline
        mov eax,HDRAW
        call exec

        call [scanlinehook]             ;do mapper IRQ
        mov eax,HBLANK
        call exec

        test [ctrl1],CR1_OBJ+CR1_BG     ;update BG ptr
        jz fr6
        mov eax,[vmaddr]
        mov edi,[vmaddr]
        add eax,001000000000000b
        and edi,000001111100000b
        and eax,111100000000000b
        mov ebp,[vmaddr2]
        test eax,111000000000000b
        jnz fr8
        add edi,000000000100000b
        and edi,000001111100000b
        cmp edi,000001111000000b
        jne fr8
        xor edi,000101111000000b
fr8:    and ebp,000010000011111b
        xor eax,edi
        add eax,ebp
        mov [vmaddr],eax
fr6:
        cmp [striketime],-1             ;if strike was set,
        je fr3
        mov [striketime],0              ;keep it set
fr3:
        inc [scanline]
        cmp [scanline],240
        jb fr0
               ;- - - - - - - -line 240
        mov [linecycles],0
        mov eax,CYCLESPERLINE
        call exec
        call [scanlinehook]
        inc [scanline]
                ;- - - - - - - -vblank start
        mov eax,[newfps]                        ;calc fps
        cmp [ticks],eax
        jb fr1
        add eax,60
        mov [newfps],eax
        mov eax,[drawn]
        mov [drawn],0
        mov [fps],eax
fr1:
        trace tVRET,0
        or [stat],STAT_VBL                      ;set vblank
                ;- - - - - - - -line 241
NMIDELAY=1
        mov [linecycles],0
        mov eax,NMIDELAY
        call exec

        test [ctrl0],CR0_NMI                    ;check NMI
        jz fr7
        test [stat],STAT_VBL
        jz fr7
        or [int_flags],NMI
fr7:
        mov eax,CYCLESPERLINE-NMIDELAY
        call exec
        call [scanlinehook]                     ;handle mapper IRQ
        inc [scanline]
fr2:            ;- - - - - - - -lines 242-260
        mov [linecycles],0
        mov eax,CYCLESPERLINE
        call exec
        call [scanlinehook]                     ;handle mapper IRQ
        inc [scanline]
        cmp [scanline],261
        jb fr2
                ;- - - - - - - -line 261
        mov [linecycles],0
        and [stat],not STAT_VBL                 ;clear VBLANK
        mov [striketime],-1                     ;clear STRIKE
        mov eax,HDRAW;CYCLESPERLINE;hdraw?
        call exec
        call [scanlinehook]                     ;handle mapper IRQ

        mov [bgskip],0                          ;BG change
        test [ctrl1],CR1_OBJ+CR1_BG     ;screen on?
        jz fr99
        mov eax,[vmaddr2]               ;setup vmaddr for bg drawing
        mov [vmaddr],eax
fr99:
        jmp frame
;-------------------------------
exec:
        add [linecycles],eax
        add [framecycles],eax
        add [cycles],eax
        js to2                  ;catch negative cycles
        restore6502
        fetch 0
timeout:
        save6502
to2:    ret
;----------------------------------------------------------------------------
interrupt:;
;----------------------------------------------------------------------------
res:
        test [int_flags],RES                    ;RESET?
        jnz reset
nmi:
        test [int_flags],NMI                    ;NMI?
        jz irq
        and [int_flags],not NMI

        sub [cycles],3*7

        sub esi,[lastbank]
        mov eax,esi
        push16                                  ;save PC
        encodeP(R)                              ;save P (break flag clear)
        push8 al
        or [DIflag],I                           ;disable IRQ
        mov edi,[memmap+7*4]
        movzx esi,word ptr [edi+NMI_VECTOR]
        encodePC                                ;get NMI vector
irq:
        test [int_flags],IRQ                    ;IRQ?
        jz debug1
        test [DIflag],I                        ;IRQ disabled?
        jnz debug1

        sub [cycles],3*7
        trace tIRQ,0
        sub esi,[lastbank]
        mov eax,esi
        push16                                  ;save PC
        encodeP(R)                              ;save P (break flag clear)
        push8 al
        or [DIflag],I                           ;disable IRQ
        mov edi,[memmap+7*4]
        movzx esi,word ptr [edi+IRQ_VECTOR]
        encodePC                                ;get IRQ vector
debug1:
if DEBUG
        test [int_flags],DEBUG1+DEBUG2          ;DEBUG1/2?
        jz debug3
        kbtest(KB_F12)          ;hold to avoid debug break
        jnz db0
        jmp debug                               ;enter debugger
db0:
        and [int_flags],not DEBUG1+DEBUG2
debug3:
        test [int_flags],DEBUG3                 ;DEBUG3?
        jz debug4
        mov eax,esi
        sub eax,[lastbank]
        cmp [break_addr],eax                    ;check breakpoint address
        je debug                                ;enter debugger if PC=brkpoint
debug4:
        test [int_flags],DEBUG4                 ;DEBUG4?
        jz debug5
        mov eax,[break_frame]
        cmp [framecount],eax
        je debug
debug5:
        test [int_flags],DEBUG5                 ;DEBUG5?
        jz done
        mov eax,[break_line]
        cmp [scanline],eax
        je debug
else
        and [int_flags],not DEBUGALL
endif
done:
        test [cycles],-1                        ;catch negative cycles
        js timeout
        fetch2                                  ;do next instruction
;----------------------------------------------------------------------------
;6502 registers:
;
;       A =DL
;       X =CH
;       Y =CL
;       S =EBX (DS offset)
;       PC=ESI (DS offset)
;
;       P: DH=N,Z
;          Cflag=C
;          Vflag=V
;          DIflag=D,I
;          Nflag=N
;
;       EAX,EDI,EBP=temp
;
;----------------------------------------------------------------------------
        align   4

op_table dd _00,_01,_??,_??,_??,_05,_06,_??,_08,_09,_0A,_??,_??,_0D,_0E,_??
         dd _10,_11,_??,_??,_??,_15,_16,_??,_18,_19,_??,_??,_??,_1D,_1E,_??
         dd _20,_21,_??,_??,_24,_25,_26,_??,_28,_29,_2A,_??,_2C,_2D,_2E,_??
         dd _30,_31,_??,_??,_??,_35,_36,_??,_38,_39,_??,_??,_??,_3D,_3E,_??
         dd _40,_41,_??,_??,_??,_45,_46,_??,_48,_49,_4A,_??,_4C,_4D,_4E,_??
         dd _50,_51,_??,_??,_??,_55,_56,_??,_58,_59,_??,_??,_??,_5D,_5E,_??
         dd _60,_61,_??,_??,_??,_65,_66,_??,_68,_69,_6A,_??,_6C,_6D,_6E,_??
         dd _70,_71,_??,_??,_??,_75,_76,_??,_78,_79,_??,_??,_??,_7D,_7E,_??
         dd _??,_81,_??,_??,_84,_85,_86,_??,_88,_??,_8A,_??,_8C,_8D,_8E,_??
         dd _90,_91,_??,_??,_94,_95,_96,_??,_98,_99,_9A,_??,_??,_9D,_??,_??
         dd _A0,_A1,_A2,_??,_A4,_A5,_A6,_??,_A8,_A9,_AA,_??,_AC,_AD,_AE,_??
         dd _B0,_B1,_??,_??,_B4,_B5,_B6,_??,_B8,_B9,_BA,_??,_BC,_BD,_BE,_??
         dd _C0,_C1,_??,_??,_C4,_C5,_C6,_??,_C8,_C9,_CA,_??,_CC,_CD,_CE,_??
         dd _D0,_D1,_??,_??,_??,_D5,_D6,_??,_D8,_D9,_??,_??,_??,_DD,_DE,_??
         dd _E0,_E1,_??,_??,_E4,_E5,_E6,_??,_E8,_E9,_EA,_??,_EC,_ED,_EE,_??
         dd _F0,_F1,_??,_??,_??,_F5,_F6,_??,_F8,_F9,_??,_??,_??,_FD,_FE,_??

Nflag           db ?                    ;N=bit 7 (rest=undefined)
Cflag           db ?                    ;C=bit 0 (rest=undefined)
Vflag           db ?                    ;V=(nonzero)
DIflag          db ?                    ;D,I=bits 3,2 (rest=0)

                align 4

_Z_A            dd      ?               ;6502 state temp holding space
_X_Y            dd      ?
_S              dd      ?               ;pointer, not actual value
_PC             dd      ?
lastbank        dd      ?               ;last memmap value added to PC (used to calculate current PC)
lastaddr        dd      ?               ;addr of last instruction executed

int_flags       dd      0               ;CPU interrupt/misc flags

framecycles     dd      0               ;framecycles-cycles=cycles this frame
linecycles      dd      0               ;linecycles-cycles=cycles this scanline
cycles          dd      0               ;PPU cycles til timeout

scanline        dd      0               ;what scanline we're on

                align 4

ticks           dd      0               ;60Hz clock tick counter
framecount      dd      0               ;NES frames completed
drawn           dd      0               ;frames actually drawn
fps             dd      0               ;FPS
newfps          dd      0               ;when to get next FPS

scanlinehook    dd      ?               ;called every scanline
mapperreset     dd      ?               ;called on CPU reset

oldctrl1        db      ?               ;for checking mono flag
;----------------------------------------------------------------------------
        end
